Version 2 of Reactable Quips by Michael Martin begins here. "A table-based approach to NPC conversation chains, as well as allowing rules to fire on lines of conversation." [Version 2: Modified "if index is the noun" to "if index is the number understood" to compensate for Inform 7's improved type checking in 3R85. Improved the output of REPEAT, and added RECAP as a synonym.] [Version 1: Initial release.] [Several issues and uglinesses remain within this code, and may cause problems or become unnecessary in later versions of Inform 7.] [ISSUE: We cannot simply understand "[number]" as responding with; this breaks all kinds of error reporting in the parser. For example, > SOMEUNKNOWNVERB gives us "You may not name an object", not "That's not a verb I recognise."] [ISSUE: We also cannot transform "[number]" into "respond with [number]" after reading the player's command; for some reason this produces a spurious newline.] [ISSUE: As a result of both of the above combined, there is a "secret action" called "waiting silently" that may conflict with real commands in the resulting application.] Section 1 - Quips A quip is a kind of value. The quips are defined by the Table of Quip Texts. The current quip is a quip that varies. The current quip is quip_null. The pertinent quip is a quip that varies. The pertinent quip is quip_null. A person has a quip called default ask quip. The default ask quip of a person is usually quip_null. A person has a quip called default tell quip. The default tell quip of a person is usually quip_null. Quipping is an activity. The last for quipping rule (this is the basic quipping rule): say "[quiptext of the current quip][paragraph break]"; To deliver the (q - quip) quip: change the current quip to q; carry out the quipping activity; let index be 0; repeat through Table of Quip Followups begin; if q is the quip entry begin; increase index by 1; say "([index]) [option entry][line break]"; end if; end repeat; if index is not 0 begin; say "[line break]"; change the pertinent quip to q; otherwise; change the pertinent quip to quip_null; end if. Requesting a recap is an action out of world applying to nothing. Understand "repeat" or "recap" as requesting a recap. Carry out requesting a recap: let index be 0; repeat through Table of Quip Followups begin; if the quip entry is the pertinent quip begin; increase index by 1; if index is 1, say "The available options are:[paragraph break]"; say "([index]) [option entry][line break]"; end if; end repeat; if index is 0 then say "(No responses are currently available.)". Responding with is an action applying to one number. Understand "respond with [number]" as responding with. [This is the hack for properly parsing and replying to commands consisting just of a number.] Waiting silently is an action applying to nothing. Understand "wait silently" as waiting silently. Report waiting silently: do nothing. After reading a command: if the player's command matches "[a number]" begin; try responding with the number understood; replace the player's command with "wait silently"; end if. [End of hack.] Carry out responding with when the pertinent quip is quip_null (this is the can't talk out of conversations rule): say "(No conversation responses are necessary at present.)". Carry out responding with when the pertinent quip is not quip_null: let index be 0; repeat through Table of Quip Followups begin; if the quip entry is the pertinent quip begin; increase index by 1; if index is the number understood begin; deliver the result entry quip; rule succeeds; end if; end if; end repeat; say "(Valid results range from 1-[index].)". Instead of doing something other than requesting a recap, responding with, or waiting silently when the pertinent quip is not quip_null (this is the force conversation rule): say "(I need to get some kind of reaction from you to continue the scene. Enter a number, or say REPEAT to reacquaint yourself with your options.)" instead. A procedural rule: move the force conversation rule to before the instead rules. A procedural rule when the pertinent quip is not quip_null: ignore the turn sequence. Section 2 - Hitword-based conversation Instead of asking someone about something: repeat through Table of Ask Results begin; if the noun is the NPC entry begin; if the topic understood includes topic entry begin; deliver the result entry quip; rule succeeds; end if; end if; end repeat; if the noun is a person begin; say "[quiptext of the default ask quip of the noun][paragraph break]"; rule succeeds; end if; say "(BUG: Managed to talk to [a noun], who is not a person.)". Telling someone about something is speech. Answering someone that something is speech. Instead of speech: repeat through Table of Tell Results begin; if the noun is the NPC entry begin; if the topic understood includes topic entry begin; deliver the result entry quip; rule succeeds; end if; end if; end repeat; if the noun is a person begin; say "[quiptext of the default tell quip of the noun][paragraph break]"; rule succeeds; end if; say "(BUG: Managed to talk to [a noun], who is not a person.)" Section 3 - The basic tables Table of Quip Texts quip quiptext quip_null "You can't think of anything to say on that topic." Table of Quip Followups quip option result a quip text a quip Table of Ask Results NPC topic result a person a topic a quip Table of Tell Results NPC topic result a person a topic a quip Reactable Quips ends here. ---- DOCUMENTATION ---- Reactable Quips provides a table-driven conversation system for NPCs that allows a mixture of traditional ask/tell and menu-based systems. The intended model is that under normal circumstances, the player character may initiate conversation by asking or telling an NPC about a topic. That NPC will then respond. However, NPCs may occasionally say or do things that demand or imply some kind of reaction from the PC -- the player must then choose some option off a menu to characterize the reaction. Regardless of the intended model, it is quite possible to use the extension to implement a pure ask/tell system. The most fundamental concept in the extension is the "quip". Quips are values, not things; they are used to index into the quip tables. Thus, the one task we must always perform is filling in the Table of Quip Texts. A default table is provided by the extension, so you will need to continue the table in your own code: Table of Quip Texts (continued) quip quiptext greeting "'Why, hello there!'" discuss weather "'Looks like rain, or my name isn't George Washington.'" standoff "'What's it to you, Mac?'" We then (if we are using the ask/tell model) use the Table of Ask Results and Table of Tell Results to attach quips to NPCs and topics. The topics may be patterns, much like understanding commands as actions are. However, the library will match against any text that contains the topic (much like Example 233: "Complimentary Peanuts"). The results are quips. Table of Ask Results (continued) NPC topic result Bob "weather" or "nice day" discuss weather Table of Tell Results (continued) NPC topic result Bob "hi/hello" greeting People have a "default ask quip" and "default tell quip" that can be used to give a generic response to unknown topics. This defaults to "You can't think of anything to say on that topic." We can also script quip delivery: Instead of examining Bob, deliver the greeting quip. Quips can be attached to rules; however, quips aren't things, and so can't be treated as "something" or "anything." Instead, we use rulebooks associated with the quipping activity: Before quipping when the current quip is greeting: say "You walk up and say hello." Quips may require a reaction. Possible responses (and the quips those responses lead to) are stored in the Table of Quip Followups: Table of Quip Followups (continued) quip option result greeting "Make small talk" discuss weather greeting "Get down to business" standoff If a quip is in the table of quip followups, the game will not progress until a choice has been made. If a quip does not appear in the table of quip followups, then after delivering the quip, normal gameplay resumes. Example: ** When Primates Collide - matching important words in a phrase, or matching complete phrases, and reacting to quips with rules. Note that in some versions of Inform 7, this code may not work if you simply cut and paste it out of the Documentation window; the tables will not render properly in the Source window. Copy it out of the actual Documentation file instead. "When Primates Collide" Include Reactable Quips by Michael Martin. Use American dialect, the serial comma, and no scoring. Horace's House is a room. A man called Horace is here. "Your eccentric neighbor Horace is here, with a T-shirt that says 'TELL ME ABOUT YOURSELF.'" Table of Quip Texts (continued) quip quiptext suggest monkeys "'That's nice, I suppose. But have I told you how awesome monkeys are? You should ask me about monkeys!'" yay monkeys "'Monkeys are awesome! Anyone with [italic type]any[roman type] sense loves monkeys. Did you know? It was humans who unleashed Zero Wing on an unsuspecting universe.'" hate aybabtu "Horace unleashes an unearthly howl. 'AIIIEEEEE! NO! Speak of it not! Never again! Hate you forever! Die die die!!!!'[paragraph break]He leaps for your throat, wrestles you to the ground, and pummels the consciousness out of you. Death will follow soon enough...[paragraph break]" apes ok "'They're OK, I guess, but they're not nearly as great as monkeys.'" humans lousy "'Humans in general are vastly inferior to monkeys.'" kindred spirit "'Finally! A kindred spirit! My quest is finally over. Take this briefcase as a token of my appreciation.'[paragraph break]He hands you a briefcase full of solid gold Krugerrands.[paragraph break]" speciesist "'Oh, you're just speciesist like the rest of them.'" Table of Quip Followups (continued) quip option result humans lousy "Fervently agree" kindred spirit humans lousy "Shrug indifferently" speciesist Table of Ask Results (continued) NPC topic result Horace "monkeys" yay monkeys Horace "lemurs/apes/gibbons/orangutans/bonobos/gorillas" apes ok Horace "humans/people/me/you/myself/yourself" humans lousy Horace "All his/her/your base" or "All his/her/your base are belong to us/you/me" or "AYBABTU" hate aybabtu Table of Tell Results (continued) NPC topic result Horace "self/me/myself" suggest monkeys After quipping when the current quip is hate aybabtu: end the game saying "You have no chance to survive make your time". After quipping when the current quip is kindred spirit: end the game in victory. test winning with "ask horace about people / 1". test me with "tell horace about myself / ask horace about how awesome monkeys are / ask horace about humans / go east / repeat / 2 / ask horace about gibbons / ask horace about all his base".